/**
 * 
 */
package compilador.analizadorSintactico.categoriasSintacticas;

import java.util.ArrayList;

import javax.swing.tree.DefaultMutableTreeNode;

import compilador.analizadorLexico.simbolos.SimboloLexico;
import compilador.analizadorSemantico.tablaSimbolos.TablaSimboloSemantico;
import compilador.interfaces.Asignable;
import compilador.interfaces.Sentencia;

/**
 * @author Nolberto Castellanos Rodriguez
 * @author Yurani Alejandra Salamanca Lotero
 *
 * Clase que representa la declaracion de una  variable
 */
public class Variable implements Sentencia{

	
//	-------------------------------------------------------------------------------------------------
//	ATRIBUTOS
//	-------------------------------------------------------------------------------------------------

	/**
	 * Atributo que contiene el Tipo de dato de la variable
	 */
	private TipoDato tipoDato;
	
	/**
	 *  Atributo que contiene el valor del indentificador de variable
	 */
	private SimboloLexico indentificadorVariable;
	
	/**
	 *  Atributo que contiene el valor de asignacion
	 */
	private Asignable valor;

	
//	-------------------------------------------------------------------------------------------------
//	CONSTRUCTOR
//	-------------------------------------------------------------------------------------------------

	/**
	 * Constructor que permite crear una variable
	 * @param tipoDato. Tipo de dato de una variable
	 * @param indentificadorVariable. Nombre de una variable
	 * @param valor. El valor que tiene aseginado una variable
	 */
	public Variable(TipoDato tipoDato, SimboloLexico identificadorVariable,
			Asignable valor) {
		super();
		this.tipoDato = tipoDato;
		this.indentificadorVariable = identificadorVariable;
		this.valor = valor;
	}
	
//	-------------------------------------------------------------------------------------------------
//	METODOS
//	-------------------------------------------------------------------------------------------------	
	
	/* (non-Javadoc)
	 * @see compilador.interfaces.Sentencia#AnalizarSemantica(compilador.analizadorSemantico.tablaSimbolos.TablaSimboloSemantico, java.util.ArrayList, java.lang.String, java.lang.String)
	 */
	@Override
	public void AnalizarSemantica(TablaSimboloSemantico ts,
			ArrayList<SimboloError> errores, String claseActual,
			String metodoActual) {
		if(!this.tipoDato.getTipoDato().getLexema().equals(this.valor.determinarTipoDato(ts, claseActual, metodoActual))){
			errores.add(new SimboloError("Los tipos de los campos no encajan", tipoDato.getTipoDato().getFila(), tipoDato.getTipoDato().getColumna()));
		}
		
	}
	
	/**
	 * Metodo que permite agregar hojas al nodo de la clase
	 * @return el nodo de la clase con sus hojas
	 */
	public DefaultMutableTreeNode getArbolVisual(){
		DefaultMutableTreeNode miRaiz =  new  DefaultMutableTreeNode("Variable");
		
		if (tipoDato != null) 
			miRaiz.add(tipoDato.getArbolVisual());
		
		miRaiz.add(new DefaultMutableTreeNode(indentificadorVariable.getLexema()));
		
		if (valor != null)
			miRaiz.add(valor.getArbolVisual());
		return miRaiz;
	}

	/* (non-Javadoc)
	 * @see co.edu.uniquindio.ingesis.analizadorSemantico.interfaces.Sentencia#getJavaCode()
	 */
	@Override
	public String getJavaCode() {
		String retornable = "";
		
		if(tipoDato != null)
			retornable += tipoDato.getTipoDato().getLexema();
		
		if(indentificadorVariable != null)
			retornable+= " "+indentificadorVariable.getLexema();
		
		if(valor != null)
			retornable = "= "+valor.getJavaCode();
		
		retornable+=";\n";
		
		return retornable;
	}
	
	
//	-------------------------------------------------------------------------------------------------
//	Getters and Setters
//	-------------------------------------------------------------------------------------------------

	
	/**
	 * Metodo que nos retorna el valor de tipoDato
	 * @return  tipoDato. Valor retornado
	 */
	public TipoDato getTipoDato() {
		return tipoDato;
	}

	/**
	 * Metodo que permite asignar el valor de tipoDato
	 * @param tipoDato. Valor a asignar tipoDato
	 */
	public void setTipoDato(TipoDato tipoDato) {
		this.tipoDato = tipoDato;
	}

	/**
	 * Metodo que nos retorna el valor de indentificadorVariable
	 * @return  indentificadorVariable. Valor retornado
	 */
	public SimboloLexico getIndentificadorVariable() {
		return indentificadorVariable;
	}

	/**
	 * Metodo que permite asignar el valor de indentificadorVariable
	 * @param indentificadorVariable. Valor a asignar indentificadorVariable
	 */
	public void setIndentificadorVariable(SimboloLexico indentificadorVariable) {
		this.indentificadorVariable = indentificadorVariable;
	}

	/**
	 * Metodo que nos retorna el valor de valor
	 * @return  valor. Valor retornado
	 */
	public Asignable getValor() {
		return valor;
	}

	/**
	 * Metodo que permite asignar el valor de valor
	 * @param valor. Valor a asignar valor
	 */
	public void setValor(Asignable valor) {
		this.valor = valor;
	}
}
